/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.kylingroup.Desktop;

import com.kylingroup.Desktop.Bean.Bean_Plugin;
import com.kylingroup.Desktop.DAO.Dao_Plugin;
import com.kylingroup.Desktop.PlugLoader.KGDesktopPlugloader;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.BorderPane;
import com.kylingroup.Desktop.Utils.Installer;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Node;
import javafx.scene.control.Menu;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import static org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder.controller;

/**
 * FXML Controller class
 *
 * @author kylin
 */
public class MainFrameController implements Initializable {
    @FXML
    private Tab welcomepage;
    @FXML
    private WebView webview;
    @FXML
    private BorderPane maincontentpane;
    @FXML
    private MenuItem menuinstall,menuuninstall,createDB;
    @FXML
    public TabPane workspace;
    @FXML
    public Text info;
    @FXML
    public ProgressBar progressbar;
    @FXML
    public Menu tools;
    private MainFrame application;
 
 
    public void setApp(MainFrame application){
        this.application = application;
    }
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        progressbar.setVisible(false);
        setWorkSpace();
        
        initWelcomePage();
        
        if(checkDBtable()){
            initPlugins();
        }else{
            try {  
                addTab("create db","create a database or table",null,loadContent("PaneDatabase.fxml"));
            } catch (Exception ex) {
                Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        menuinstall.setOnAction((ActionEvent event) -> {
            Installer in=new Installer(application.mainFrame,MainFrameController.this);    
        });
        menuuninstall.setOnAction((ActionEvent event) -> {
            
        });
        
        createDB.setOnAction((ActionEvent event) -> {
            try {  
                addTab("create db","create a database or table",null,loadContent("PaneDatabase.fxml"));
            } catch (Exception ex) {
                Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
            }
        });
    }
    private void initWelcomePage(){
        final WebEngine webEngine = webview.getEngine();
        webEngine.load("http://localhost:8080/kylingroup/");
    }
    
    private void setWorkSpace(){
        workspace.setTabClosingPolicy(TabPane.TabClosingPolicy.SELECTED_TAB);
    }
    
    private void addTab(String title,String tooltip,String imageurl,Node content){
        Tab tab=new Tab();
        
        if(imageurl!=null&&!imageurl.equals("")){
            Image image=new Image(getClass().getResourceAsStream(imageurl));
            ImageView imageView=new ImageView();
            imageView.setImage(image);
            tab.setGraphic(imageView);
        }
        
        tab.setText(title);
        tab.setTooltip(new Tooltip(tooltip));
        tab.setContent(content);
        SingleSelectionModel<Tab> selectionModel=workspace.getSelectionModel();
        selectionModel.select(tab);
        workspace.getTabs().add(tab);
        
    }
    
    private Node loadContent(String fxml) throws Exception {
        FXMLLoader loader = new FXMLLoader();
        InputStream in = MainFrameController.class.getResourceAsStream(fxml);
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        loader.setLocation(MainFrameController.class.getResource(fxml));
        Node content;
        try {
            content=(Node)loader.load(in);
        } finally {
            in.close();
        }
        return content;
    }
    private void initPlugins(){
        Dao_Plugin dao=new Dao_Plugin();
        dao.setConnection(MainFrame.dbconn);
            
        List list=dao.findAll();
        Iterator itor=list.iterator();
        while(itor.hasNext()){
            Bean_Plugin p=(Bean_Plugin)itor.next();
            if(p.isAutoload()){
                MenuItem item=new MenuItem(p.getName());
                item.setOnAction((ActionEvent event) -> {
                    try {
                        loadPlugin(p);
                    } catch (IOException ex) {
                        Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                });
                if(p.getCategory().equalsIgnoreCase("tools")){
                    tools.getItems().add(item);
                }
            }
            System.out.println("[plug id]:"+p.getId()+" [plug name]:"+p.getName());
        }
    }
    private void loadPlugin(Bean_Plugin p) throws IOException{
 
        URL jarurl=null;
        try{
            jarurl=new URL("file:"+p.getLocation());
            URLClassLoader urlloader=new URLClassLoader(new URL[]{jarurl});
            System.out.println("url loader:"+urlloader.toString());
            Class clazz=urlloader.loadClass(p.getClazz());
            Method ms[]=clazz.getDeclaredMethods();
//            for(int i=0;i<ms.length;i++){
//                System.out.println("method:"+ms[i].getName());
//            }
            
            if(clazz==null){
                return;
            }
            Platform.runLater(new Runnable(){
                @Override
                public void run() {
                    try {
                        Object obj=clazz.newInstance();
                        System.out.println("classname:"+obj.getClass().getName());
                        //obj.getClass().getDeclaredMethod("install",null).invoke(obj, null);
                        KGDesktopPlugloader plugloader= (KGDesktopPlugloader)obj;
                        addTab(p.getName(),p.getDescription(),null,plugloader.install());
                    } catch (InstantiationException ex) {
                        Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IllegalAccessException ex) {
                        Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            
            });
            
            
        }catch(MalformedURLException ex){
            Logger.getLogger(Installer.class.getName()).log(Level.SEVERE, null, ex);
        }catch(ClassNotFoundException ex) {
            Logger.getLogger(Installer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    public boolean checkDBtable(){
        boolean result=false;
        Connection conn=MainFrame.dbconn.getConnection();
        ResultSet rst=null;
        DatabaseMetaData dma;
        try {
            dma = conn.getMetaData();
            rst=dma.getTables(null, null, null, new String[]{"TABLE","VIEW"});
            while(rst.next()){
                if(rst.getString(4)!=null&&(rst.getString(4).equalsIgnoreCase("TABLE")||rst.getString(4).equalsIgnoreCase("VIEW"))){
                    String tablename=rst.getString(3).toLowerCase();
                    if(tablename.equalsIgnoreCase("tbplugins")){
                        result=true;
                    }else{
                        result=false;
                    }
                }else{
                    result=false;
                }
            } 
        }catch (SQLException ex){
            Logger.getLogger(MainFrameController.class.getName()).log(Level.SEVERE, null, ex);
        }finally{
            try{
                if(rst!=null){
                    rst.close();
                }
                if(conn!=null){
                    conn.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return result;
    }
}
